#!/usr/bin/env python3
"""
DBAgent - 智能数据库分析系统
基于多Agent协作架构的通用数据库分析系统
"""

import os
from dotenv import load_dotenv
import logging
from contextlib import asynccontextmanager
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse

# 导入应用模块
from app.core.config import settings
from app.core.database import DatabaseUtils
from app.api.routes import api_router
from app.api.dependencies import analysis_service_dependency, orchestrator_dependency

# 载入 .env 环境变量（确保 AI/DB 配置可用）
load_dotenv()

# 确保日志目录存在（在被 uvicorn 导入时也可用）
os.makedirs("logs", exist_ok=True)

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(filename)s:%(lineno)d - %(message)s',
    handlers=[
        logging.FileHandler('logs/dbagent.log'),
        logging.StreamHandler()
    ],
    force=True
)
logger = logging.getLogger(__name__)

# 应用生命周期管理
@asynccontextmanager
async def lifespan(app: FastAPI):
    """应用启动和关闭时的生命周期管理"""
    # 启动时
    logger.info("DBAgent 系统启动中...")
    
    # 初始化目标数据库连接（仅目标库）
    await DatabaseUtils.init_database()
    logger.info("数据库初始化完成")
    
    # 启动时测试数据库连接并输出表结构
    try:
        # 基础连通性测试
        ping = DatabaseUtils.execute_target_query("SELECT 1")
        _ = ping.fetchone()
        logger.info("数据库连通性检测成功 (SELECT 1)")
        
        # 列出表并打印每张表的字段信息（限制前20张表，避免日志过大）
        tables = DatabaseUtils.get_target_tables()
        logger.info(f"检测到 {len(tables)} 张表")
        for t in tables[:20]:
            schema = DatabaseUtils.get_target_table_schema(t) or {}
            cols = schema.get("columns") or []
            # 只打印列名，限制最多 50 列
            col_names = []
            for c in cols[:50]:
                if isinstance(c, dict):
                    name = c.get("column_name") or c.get("COLUMN_NAME") or c.get("name") or c.get("Field")
                    if name:
                        col_names.append(str(name))
                else:
                    col_names.append(str(c))
            logger.info(f"表 {t} 字段({len(cols)}): {', '.join(col_names)}")
            if len(cols) > 50:
                logger.info(f"表 {t} 其余字段未展示，共 {len(cols)} 列")
    except Exception as e:
        logger.error(f"启动时数据库检测失败: {e}")
    
    # 最简化版本：仅确保可连接目标数据库
    
    logger.info("DBAgent 系统启动完成！")
    
    yield
    
    # 关闭时
    logger.info("DBAgent 系统正在关闭...")
    logger.info("DBAgent 系统已关闭")

# 创建FastAPI应用
app = FastAPI(
    title="DBAgent - 智能数据库分析系统",
    description="基于多Agent协作架构的通用数据库分析系统，支持自然语言查询和智能SQL生成",
    version="0.1.0",
    docs_url="/api/docs",
    redoc_url="/api/redoc",
    openapi_url="/api/openapi.json",
    lifespan=lifespan
)

# 配置CORS
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],  # 生产环境中应该指定具体的前端域名
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# 注册路由
app.include_router(api_router, prefix="/api")

# 全局异常处理
@app.exception_handler(Exception)
async def global_exception_handler(request, exc):
    logger.error(f"全局异常: {str(exc)}", exc_info=True)
    return JSONResponse(
        status_code=500,
        content={
            "success": False,
            "message": "服务器内部错误",
            "data": None
        }
    )

# 健康检查接口
@app.get("/health", summary="健康检查")
async def health_check():
    """系统健康检查接口"""
    return {
        "success": True,
        "message": "DBAgent 系统运行正常",
        "data": {
            "service": "DBAgent",
            "version": "0.1.0",
            "status": "healthy"
        }
    }

# 根路径
@app.get("/", summary="系统首页")
async def root():
    """系统首页"""
    return {
        "success": True,
        "message": "欢迎使用 DBAgent 智能数据库分析系统",
        "data": {
            "service": "DBAgent",
            "version": "0.1.0",
            "docs": "/api/docs",
            "health": "/health"
        }
    }

if __name__ == "__main__":
    import uvicorn
    
    # 确保日志目录存在
    os.makedirs("logs", exist_ok=True)
    
    # 启动服务
    uvicorn.run(
        "main:app",
        host="0.0.0.0",
        port=8000,
        reload=True,
        log_level="info"
    )
